import { ElMessage, ElNotification } from 'element-plus'
import { auth } from './auth'

/**
 * 全局错误处理器
 */
export const errorHandler = {
    /**
     * 处理API错误
     * @param {Object} error - 错误对象
     * @param {Object} options - 配置选项
     */
    handleApiError(error, options = {}) {
        const {
            showMessage = true,
            showNotification = false,
            customMessage = null,
            redirectOnAuth = true
        } = options

        console.error('API错误处理:', error)

        // 处理认证错误
        if (error.code === 401 || error.isAuthError) {
            console.log('处理认证错误')
            
            // 清除认证信息
            auth.clearAuth()
            
            const message = customMessage || error.message || 'Token已过期，请重新登录'
            
            if (showMessage) {
                ElMessage.error(message)
            }
            
            if (showNotification) {
                ElNotification.error({
                    title: '认证失败',
                    message: message,
                    duration: 3000
                })
            }
            
            // 重定向到登录页
            if (redirectOnAuth && !window.location.hash.includes('/login')) {
                const currentPath = window.location.hash.replace('#', '') || '/dashboard'
                setTimeout(() => {
                    window.location.href = `/#/login?redirect=${encodeURIComponent(currentPath)}`
                }, 1000)
            }
            
            return
        }
        
        // 处理其他HTTP错误
        const message = this.getErrorMessage(error, customMessage)
        
        if (showMessage) {
            ElMessage.error(message)
        }
        
        if (showNotification) {
            ElNotification.error({
                title: '请求失败',
                message: message,
                duration: 3000
            })
        }
    },

    /**
     * 获取错误消息
     * @param {Object} error - 错误对象
     * @param {String} customMessage - 自定义消息
     * @returns {String} 错误消息
     */
    getErrorMessage(error, customMessage) {
        if (customMessage) return customMessage
        
        // 根据错误码返回友好的错误消息
        const errorMessages = {
            400: '请求参数错误',
            401: '认证失败，请重新登录',
            403: '权限不足，无法访问',
            404: '请求的资源不存在',
            405: '请求方法不允许',
            408: '请求超时',
            429: '请求过于频繁，请稍后重试',
            500: '服务器内部错误',
            502: '网关错误',
            503: '服务暂时不可用',
            504: '网关超时'
        }
        
        if (error.code && errorMessages[error.code]) {
            return errorMessages[error.code]
        }
        
        return error.message || '网络请求失败，请稍后重试'
    },

    /**
     * 处理Vue组件中的错误
     * @param {Object} error - 错误对象
     * @param {Object} vm - Vue实例
     * @param {String} info - 错误信息
     */
    handleVueError(error, vm, info) {
        console.error('Vue组件错误:', error, info)
        
        // 如果是认证相关错误，特殊处理
        if (error.code === 401 || error.isAuthError) {
            this.handleApiError(error)
            return
        }
        
        ElMessage.error('页面出现错误，请刷新重试')
    },

    /**
     * 处理Promise未捕获的错误
     * @param {Object} event - 错误事件
     */
    handleUnhandledRejection(event) {
        console.error('未处理的Promise错误:', event.reason)
        
        // 如果是认证错误，特殊处理
        if (event.reason && (event.reason.code === 401 || event.reason.isAuthError)) {
            this.handleApiError(event.reason)
            event.preventDefault() // 阻止默认的错误处理
            return
        }
        
        // 其他错误的处理
        ElMessage.error('系统出现异常，请稍后重试')
    }
}

/**
 * 安装全局错误处理器
 * @param {Object} app - Vue应用实例
 */
export function installErrorHandler(app) {
    // Vue组件错误处理
    app.config.errorHandler = errorHandler.handleVueError
    
    // 全局未捕获的Promise错误处理
    window.addEventListener('unhandledrejection', errorHandler.handleUnhandledRejection)
    
    // 全局JavaScript错误处理
    window.addEventListener('error', (event) => {
        console.error('全局JavaScript错误:', event.error)
        ElMessage.error('页面出现错误，请刷新重试')
    })
}

export default errorHandler 